home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 2007-03-19 | 59.1 KB | 1,957 lines
#!/usr/bin/env python # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # Authors: Quinn Storm (quinn@beryl-project.org) # Copyright (C) 2007 Quinn Storm import berylsettings import gtk import gtk.gdk import gobject import os import re gdk = gtk.gdk from xml.sax.saxutils import escape as EscapeMarkup APP = 'beryl-settings' DIR = 'locale' import locale import gettext locale.setlocale(locale.LC_ALL, '') gettext.bindtextdomain(APP, DIR) gettext.textdomain(APP) _ = gettext.gettext DATADIR = "/usr/share" IMAGEDIR = "/usr/share/bsm/images" PREFIX = "/usr" VERSION = "0.2.1" BaseDir = DATADIR+"/bsm/images" CatImages = {"wm":"window-management.svg", "accessibility":"accessibility.svg", "desktop":"desktop.svg", "effects":"visual-effects.svg", "misc":"extras.svg", "devel":"development.svg", "__general":"general-settings.svg", "imageformat":"images.svg"} GenStore = gtk.TreeStore( gobject.TYPE_STRING, #Entry Name gobject.TYPE_STRING, #Key binding gobject.TYPE_BOOLEAN, #key enabled gobject.TYPE_STRING, #Button binding gobject.TYPE_BOOLEAN, #button enabled gobject.TYPE_STRING, #plugin name gobject.TYPE_STRING, #setting name ) GenStoreFiltered = GenStore.filter_new() EdgeStore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_BOOLEAN) EdgeDesc = [ [("Top Left Corner","TopLeft"), ("Top Edge","Top"), ("Top Right Corner","TopRight")], [("Left Edge","Left"),("..",""),("Right Edge","Right")], [("Bottom Left Corner","BottomLeft"), ("Bottom Edge","Bottom"), ("Bottom Right Corner","BottomRight")] ] class FooClass: def __init__(self): pass Ctx = berylsettings.Context() Ctx.Read() hideshowall = None AllowUpdate = True CurProfLab = None AllCats = [] AllSettings = [] EdgeBoxes = [] tooltips = gtk.Tooltips() def WriteSettings(): Ctx.Write() berylsettings.send_reload() def QuitAll(v): gtk.main_quit() def SetPluginsEnabled(): for Ca in AllCats: for Pl in Ca.Plugins: if (Pl.Button): Pl.Button.props.active = Pl.Plugin.Enabled def SetWidgetsFromValues(): global CurProfLab global AllowUpdate AllowUpdate = False if (CurProfLab): prof = Ctx.Profile if (prof == None): prof = _('<Default>') prof = EscapeMarkup(prof) CurProfLab.set_markup(_("Current Profile: <b>%s</b>")%prof) SetPluginsEnabled() for set in AllSettings: SetWidgetsForSetting(set.Setting) AllowUpdate = True def MoveRow(bwid,bothinf): dir = bothinf[0] inf = bothinf[1] sel = inf.TreeView.get_selection().get_selected() if (not sel[0]): return Iter = sel[1] Miter = None if (dir == 0): MIter = inf.ListStore.get_iter_first() while(MIter and inf.ListStore.iter_next(MIter)): if (inf.ListStore.get_string_from_iter(inf.ListStore.iter_next(MIter)) == inf.ListStore.get_string_from_iter(Iter)): break MIter = inf.ListStore.iter_next(MIter) if (not inf.ListStore.iter_next(MIter)): MIter = None else: MIter = inf.ListStore.iter_next(Iter) if (MIter): istr = inf.ListStore.get_string_from_iter(MIter) inf.ListStore.swap(Iter,MIter) SetSettingFromWidgets(inf.Setting) Iter = inf.ListStore.get_iter_from_string(istr) inf.TreeView.get_selection().select_iter(Iter) def AddRow(plb,set): inspos = set.TreeView.get_selection().get_selected()[1] if (inspos): Iter = set.ListStore.insert_after(inspos) else: Iter = set.ListStore.append() set.ListStore.set(Iter,0,_('<New Value>')) SetSettingFromWidgets(set) def DelRow(plb,set): delpos = set.TreeView.get_selection().get_selected()[1] if (not delpos): return set.ListStore.remove(delpos) SetSettingFromWidgets(set) def AddImageFilters(fil): for plugin in Ctx.ActivePlugins: for feature in Ctx.Plugin(plugin).Provides: if (feature.split(':')[0]=='imageext'): fil.add_pattern('*.'+feature.split(':')[1]) if (feature.split(':')[0]=='imagemime'): fil.add_mime_type(feature.split(':')[1]) def UpdatePrev(file_chooser, preview): filename = file_chooser.get_preview_filename() try: pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(filename, 128, 128) preview.set_from_pixbuf(pixbuf) have_preview = True except: have_preview = False file_chooser.set_preview_widget_active(have_preview) return def BrowseDlg(set): if (set.Setting.HasHint("directory")): action = gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER else: action = gtk.FILE_CHOOSER_ACTION_OPEN dlg = gtk.FileChooserDialog(_("Browse for %s...")%set.Setting.ShortDesc,MainWindow, action,(gtk.STOCK_OPEN,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) if (not set.Setting.HasHint("directory")): fil = gtk.FileFilter() fil.set_name(_("All Files")) fil.add_pattern("*") dlg.add_filter(fil) if (set.Setting.HasHint("image")): preview = gtk.Image() dlg.set_preview_widget(preview) dlg.connect("update-preview",UpdatePrev,preview) if (set.Setting.HasHint("pngonly")): fil = gtk.FileFilter() fil.set_name(_("PNG Images")) fil.add_pattern("*.png") fil.add_mime_type(_("image/png")) dlg.add_filter(fil) dlg.set_filter(fil) else: fil = gtk.FileFilter() fil.set_name(_("Images")) AddImageFilters(fil) dlg.add_filter(fil) dlg.set_filter(fil) ret = dlg.run() val = None if (ret == gtk.RESPONSE_OK): if (dlg.get_filename()): val = dlg.get_filename() dlg.destroy() del dlg return val def BrowseEntry(plb,set): val = BrowseDlg(set) if (val): set.Entry.set_text(val) SetSettingFromWidgets(set) def BrowseRow(plb,set): val = BrowseDlg(set) if (val): inspos = set.TreeView.get_selection().get_selected()[1] if (inspos): Iter = set.ListStore.insert_after(inspos) else: Iter = set.ListStore.append() set.ListStore.set(Iter,0,val) SetSettingFromWidgets(set) def ChainDisablePlugin(plugin): for plg in Ctx.ActivePlugins: pp = Ctx.Plugin(plg) for pr in plugin.Provides: if (pp.Requires.__contains__(pr)): ChainDisablePlugin(pp) break plugin.Enabled = False def SatisfyDeps(feature): #returns list of plugins that provide feature ret = [] for plugin in Ctx.Plugins: if (plugin.Provides.__contains__(feature)): ret = ret+[plugin] return ret def TryEnablePlugin(plugin): #first make sure it doesn't conflict for feature in plugin.Provides: for p in Ctx.ActivePlugins: if (Ctx.Plugin(p).Provides.__contains__(feature)): msg = _("Can't enable plugin <b>%s</b> because it\nprovides feature <i>%s</i> which is also\nprovided by enabled plugin <b>%s</b>.")%(plugin.ShortDesc,feature,Ctx.Plugin(p).ShortDesc) dlg = gtk.Dialog(_("Can't Enable Plugin"),MainWindow,gtk.DIALOG_MODAL,(_("Disable Conflicting Plugin"),gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) hb = gtk.HBox() vb = gtk.VBox() img = gtk.image_new_from_stock(gtk.STOCK_DIALOG_ERROR,gtk.ICON_SIZE_DIALOG) lab = gtk.Label() lab.set_markup(msg) vb.pack_start(img,False,False) hb.pack_start(vb,False,False) hb.pack_start(lab,True,True) dlg.vbox.pack_start(hb,True,True) dlg.vbox.show_all() dlg.set_title(_("Can't Enable Plugin")) ret = dlg.run() dlg.destroy() if (ret == gtk.RESPONSE_CANCEL): return False else: ChainDisablePlugin(Ctx.Plugin(p)) needs = [] for req in plugin.Requires: noneed = False for p in Ctx.ActivePlugins: if Ctx.Plugin(p).Provides.__contains__(req): noneed = True break if not noneed: needs = needs+[req] for need in needs: dep = SatisfyDeps(need) if len(dep) == 0: msg = _("Couldn't find any plugins\nthat provide feature <i>%s</i>\nrequired by plugin <b>%s</b>")%(need,plugin.ShortDesc) dlg = gtk.MessageDialog(MainWindow,gtk.DIALOG_MODAL,gtk.MESSAGE_ERROR,gtk.BUTTONS_OK) dlg.set_markup(msg) dlg.set_title(_("Can't Enable Plugin")) dlg.run() dlg.destroy() return False dlg = gtk.Dialog(_("Select Plugin to Enable"),MainWindow,gtk.DIALOG_MODAL,(gtk.STOCK_OK,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) icmb = gtk.combo_box_new_text() msg = _("The plugin <b>%s</b> requires the feature\n<i>%s</i> which is provided by the following\nplugins. Please select which to enable.")%( plugin.ShortDesc,need) lab = gtk.Label() lab.set_markup(msg) dlg.vbox.pack_start(lab) for p in dep: icmb.append_text(p.ShortDesc) dlg.vbox.pack_start(icmb,False,False) dlg.vbox.show_all() icmb.set_active(0) ret = dlg.run() val = icmb.get_active() dlg.destroy() if (ret == gtk.RESPONSE_CANCEL): return if (val == -1): return if not TryEnablePlugin(dep[val]): return False plugin.Enabled = True return True def PluginButtonClicked(plb,pld): global hideshowall global AllowUpdate if AllowUpdate: if (plb.props.active): if not TryEnablePlugin(pld.Plugin): AllowUpdate = False SetPluginsEnabled() AllowUpdate = True return else: ChainDisablePlugin(pld.Plugin) AllowUpdate = False SetPluginsEnabled() UpdateBindingsList(hideshowall.props.active) AllowUpdate = True WriteSettings() def CatClicked(wid,event,CatInfo): for category in AllCats: category.Image.set_from_pixbuf(category.BasePixbuf) category.Label.set_markup("<small>%s</small>"%(category.Category.ShortDesc)) CatInfo.Image.set_from_pixbuf(CatInfo.HighPixbuf) CatInfo.Label.set_markup("<small><i><b>%s</b></i></small>"%(CatInfo.Category.ShortDesc)) if (PlugArea.get_child()): PlugArea.remove(PlugArea.get_child()) PlugArea.add(CatInfo.Widget) CatInfo.Widget.show_all() def PlugClicked(wid,event,plgInfo): pl = AllCats[plgInfo.CatIndex] for plugin in pl.Plugins: plugin.Image.set_from_pixbuf(plugin.BasePixbuf) plugin.Label.set_markup("<small>%s</small>"%(plugin.Plugin.ShortDesc)) plgInfo.Image.set_from_pixbuf(plgInfo.HighPixbuf) plgInfo.Label.set_markup("<small><i><b>%s</b></i></small>"%(plgInfo.Plugin.ShortDesc)) if (pl.Container.get_child()): pl.Container.remove(pl.Container.get_child()) pl.Container.add(plgInfo.Widget) pl.Container.show_all() def TrySetBinding(set,typ,val): v0 = set.Value[0] v1 = set.Value[1] v2 = set.Value[2] v3 = set.Value[3] if (typ == 0): set.Value = [val,v1,v2,v3] else: set.Value = [v0,val,v2,v3] cfl = set.Conflicts(typ) if (len(cfl)<1): return for n in cfl[0][1]: if (n.Plugin.Name == '_'): continue if (n.Plugin.Enabled): continue cfl[0][1].remove(n) for n in cfl[0][1]: if (n.Name == set.Name and n.Plugin.Name == set.Plugin.Name): cfl[0][1].remove(n) if len(cfl[0][1])<1: return cset = cfl[0][1][0] keym = ["keyboard shortcut","mouse shortcut"] message = "Cannot set %s\n<b>%s</b> for <b>%s</b> to\n<u>%s</u> because it would conflict with\n%s <b>%s</b>\nfor <b>%s</b>."%(keym[typ], set.ShortDesc,set.Plugin.ShortDesc,val.replace('<','<'),keym[typ],cset.ShortDesc,cset.Plugin.ShortDesc) dlg = gtk.Dialog(_("Shortcut Conflict"),MainWindow,gtk.DIALOG_MODAL,("Clear Conflicting Binding",gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) lab = gtk.Label() lab.set_markup(message) hbox = gtk.HBox() vbox = gtk.VBox() hbox.pack_start(vbox,False,False) hbox.pack_start(lab,True,True) vbox.pack_start(gtk.image_new_from_stock(gtk.STOCK_DIALOG_WARNING,gtk.ICON_SIZE_DIALOG),False,False) dlg.vbox.pack_start(hbox,False,False) dlg.vbox.show_all() ret = dlg.run() dlg.destroy() if (ret == gtk.RESPONSE_CANCEL): set.Value = [v0,v1,v2,v3] else: v0 = cset.Value[0] v1 = cset.Value[1] v2 = cset.Value[2] v3 = cset.Value[3] if (typ == 0): v0 = 'Disabled' else: v1 = 'Disabled' cset.Value = [v0,v1,v2,v3] #look up cset in the list-store -.- Iter = GenStore.get_iter_first() while(Iter): PIter = GenStore.iter_children(Iter) while(PIter): SIter = GenStore.iter_children(PIter) while(SIter): vals = GenStore.get(SIter,5,6) if (vals[0] == cset.Plugin.Name and vals[1] == cset.Name): GenStore.set(SIter,1,cset.Value[0],3,cset.Value[1]) return SIter = GenStore.iter_next(SIter) PIter = GenStore.iter_next(PIter) Iter = GenStore.iter_next(Iter) def BindChanged(wid,path,tex,valplus): val = valplus[0] Info = valplus[1] global AllowUpdate if not AllowUpdate: return #val is key or button (0,1) if Info: MyStore = Info.StoreFiltered else: MyStore = GenStoreFiltered Iter = MyStore.get_iter_from_string(path) if not Iter: return AllowUpdate = False if Info: vals = MyStore.get(Iter,5) set = Info.Plugin.Setting(vals[0]) else: vals = MyStore.get(Iter,5,6) set = Ctx.Plugin(vals[0]).Setting(vals[1]) TrySetBinding(set,val,tex) RIter = MyStore.convert_iter_to_child_iter(Iter) if Info: MyStore = Info.Store else: MyStore = GenStore if val == 0: MyStore.set(RIter,1,set.Value[0]) else: MyStore.set(RIter,3,set.Value[1]) WriteSettings() AllowUpdate = True def SetWidgetsForSetting(setting): #find setting in AllSettings this = None for set in AllSettings: if set.Setting.Name == setting.Name and set.Setting.Plugin.Name == setting.Plugin.Name: this = set if (this == None): return set = this.Setting if (setting.Integrated): this.Label.set_markup("<span foreground=\"blue\">%s</span>"%(set.ShortDesc)) else: this.Label.set_markup("%s"%(set.ShortDesc)) if (setting.ReadOnly): this.ResetButton.set_sensitive(False) else: this.ResetButton.set_sensitive(True) if (set.Type == 'Bool'): this.Checkbox.props.active = set.Value this.Checkbox.set_sensitive(not setting.ReadOnly) elif (set.Type == 'Int' or set.Type == 'Float'): this.SpinButton.set_value(set.Value) this.SpinButton.set_sensitive(not setting.ReadOnly) elif (set.Type == 'String' and len(set.Restrictions) == 0): this.Entry.set_text(set.Value) this.Entry.set_sensitive(not setting.ReadOnly) elif (set.Type == 'String'): for m in range(0,len(set.Restrictions)): if (set.Restrictions[m] == set.Value): this.ComboBox.set_active(m) this.ComboBox.set_sensitive(not setting.ReadOnly) elif (set.Type == 'Color'): this.ColorButton.set_color(gdk.Color(set.Value[0],set.Value[1],set.Value[2])) this.ColorButton.set_alpha(set.Value[3]) this.ColorButton.set_sensitive(not setting.ReadOnly) elif (set.Type == 'Binding' and set.Restrictions[2]): this.Checkbox.props.active = set.Value[2] this.Checkbox.set_sensitive(not setting.ReadOnly) elif (set.Type == 'List of String'): if (len(set.Restrictions)): for n in this.CheckBoxes: if (set.Value.__contains__(n.String)): n.Checkbox.props.active = True else: n.Checkbox.props.active = False else: this.ListStore.clear() for n in set.Value: Iter = this.ListStore.append() this.ListStore.set(Iter,0,n) def SetSettingFromWidgets(set): #set is assumed to be a pair(setting,wid) global AllowUpdate if (not AllowUpdate): return setting = set.Setting if (setting.Type == 'Bool'): setting.Value = set.Checkbox.props.active elif (setting.Type == 'Int' or setting.Type == 'Float'): setting.Value = set.SpinButton.get_value() elif (setting.Type == 'String' and len(setting.Restrictions) == 0): setting.Value = set.Entry.get_text() elif (setting.Type == 'String'): setting.Value = set.ComboBox.get_active_text() elif (setting.Type == 'Color'): col = set.ColorButton.get_color() al = set.ColorButton.get_alpha() setting.Value = (col.red,col.green,col.blue,al) elif (setting.Type == 'Binding' and setting.Restrictions[2]): vv = setting.Value setting.Value = [vv[0],vv[1],set.Checkbox.props.active,vv[3]] elif (setting.Type == 'List of String'): if (len(setting.Restrictions)): val = [] for n in set.CheckBoxes: if (n.Checkbox.props.active): val += [n.String] setting.Value = val else: val = [] Iter = set.ListStore.get_iter_first() while Iter: val += [set.ListStore.get(Iter,0)[0]] Iter = set.ListStore.iter_next(Iter) setting.Value = val WriteSettings() AllowUpdate = False SetWidgetsForSetting(setting) AllowUpdate = True def SimpleChangedCB(wid,set): SetSettingFromWidgets(set) def UpdateBindingsList(ShowHidden): global GenStore GenStore.clear() global EdgeStore EdgeStore.clear() s = Ctx.Plugins for p in range(0,len(s)): if (s[p].Name == '_'): nn = s[0] s[0] = s[p] s[p] = nn Iter = EdgeStore.append() EdgeStore.set(Iter,0,"<small>None</small>",1,"",2,"",3,True) if (len(EdgeBoxes) == 3): for row in range(0,3): for col in range(0,3): if (EdgeBoxes[row][col][0]): EdgeBoxes[row][col][0].set_active_iter(Iter) for p in s: if (not (ShowHidden or p.Enabled or p.Name == '_')): continue hasany = False for q in p.Settings: if q.Type == 'Binding' and q.Restrictions[3]: hasany = True if not hasany: continue Iter = EdgeStore.append() EdgeStore.set(Iter,0,"<b>%s</b>"%p.ShortDesc,3,False) for q in p.Settings: if q.Type == 'Binding' and q.Restrictions[3]: Iter = EdgeStore.append() EdgeStore.set(Iter,0,"<small>%s</small>"%q.ShortDesc,1,p.Name,2,q.Name,3,True) if len(EdgeBoxes) == 3: for row in range(0,3): for col in range(0,3): if (EdgeBoxes[row][col][1] != 0): set = Ctx.EdgeOwner(EdgeBoxes[row][col][1]) if (set): if (set.Name == q.Name and set.Plugin.Name == q.Plugin.Name): EdgeBoxes[row][col][0].set_active_iter(Iter) for p in range(1,len(s)-1): for q in range(p+1,len(s)): if (s[p].ShortDesc>s[q].ShortDesc): nn = s[p] s[p] = s[q] s[q] = nn for p in s: if (not (ShowHidden or p.Enabled or p.Name == '_')): continue hasany = False for m in p.Settings: if (m.Type == 'Binding' and (m.Restrictions[0] or m.Restrictions[1])): hasany = True break if hasany: PIter = GenStore.append(None) GenStore.set(PIter,0,p.ShortDesc,1,"",2,False,3,"",4,False,5,"",6,"") for g in p.Groups: hasany = False for s in g.SubGroups: for m in s.Settings: if (m.Type == 'Binding' and (m.Restrictions[0] or m.Restrictions[1])): hasany = True break if hasany: break if hasany: GIter = GenStore.append(PIter) GenStore.set(GIter,0,g.Name,1,"",2,False,3,"",4,False,5,"",6,"") for s in g.SubGroups: for m in s.Settings: if (m.Type == 'Binding' and (m.Restrictions[0] or m.Restrictions[1])): SIter = GenStore.append(GIter) if (m.Restrictions[0]): mv0 = m.Value[0] else: mv0 = "N/A" if (m.Restrictions[1]): mv1 = m.Value[1] else: mv1 = "N/A" if (m.Integrated): GenStore.set(SIter,0,"<span foreground=\"blue\">%s</span>"%(m.ShortDesc),1,mv0,2,m.Restrictions[0] and not m.ReadOnly, 3,mv1,4,m.Restrictions[1] and not m.ReadOnly,5,p.Name,6,m.Name) else: GenStore.set(SIter,0,m.ShortDesc,1,mv0,2,m.Restrictions[0] and not m.ReadOnly, 3,mv1,4,m.Restrictions[1] and not m.ReadOnly,5,p.Name,6,m.Name) def HideShowClick(wid): UpdateBindingsList(wid.props.active) try: statemask = gdk.SHIFT_MASK | gdk.CONTROL_MASK | gdk.MOD1_MASK | gdk.MOD2_MASK | gdk.MOD3_MASK | \ gdk.MOD5_MASK | gdk.SUPER_MASK | gdk.HYPER_MASK | gdk.META_MASK except: statemask = gdk.SHIFT_MASK | gdk.CONTROL_MASK | gdk.MOD1_MASK | gdk.MOD2_MASK | gdk.MOD3_MASK | \ gdk.MOD4_MASK | gdk.MOD5_MASK def kpe(win,ev,ent): keygot = (ev.keyval,ev.state) #check to see if its a modifier key #currently this will be a hardcoded list, should perhaps be changed later ModKeys = ['Alt_L','Alt_R','AltGr','Super_L','Super_R','Control_L','Control_R','Shift_L','Shift_R','Meta_L','Meta_R','Multi_key'] if (ModKeys.__contains__(gdk.keyval_name(ev.keyval))): return ev = gdk.event_get() win.grab_remove() gdk.keyboard_ungrab() win.destroy() keygot = (keygot[0],keygot[1]&statemask) win.destroy() if (keygot[1] == 0 and keygot[0] == gdk.keyval_from_name("Escape")): return if (keygot[1] == 0 and keygot[0] == gdk.keyval_from_name("BackSpace")): ent.set_text("Disabled") else: ent.set_text(gtk.accelerator_name(keygot[0],keygot[1])) def GetKey(wid,ent): global keygot win = gtk.Window(gtk.WINDOW_POPUP) win.set_position(gtk.WIN_POS_MOUSE) win.set_resizable(False) fram = gtk.Frame() win.add(fram) fram.set_shadow_type(gtk.SHADOW_OUT) align = gtk.Alignment(0,0,0,0) align.props.border_width = 32 str = "Please press the key on the keyboard\n" str += "you wish to modify this keyboard-shortcut\n" str += "to use from now on. Press BACKSPACE to clear,\n" str += "Press ESCAPE to cancel." lab = gtk.Label(str) fram.add(align) align.add(lab) win.show_all() while(gtk.events_pending()): gtk.main_iteration() gdk.flush() while(gtk.events_pending()): gtk.main_iteration() win.window.set_events(gdk.KEY_PRESS_MASK) gdk.keyboard_grab(win.window,True) win.grab_add() win.grab_focus() keygot = None win.connect("key-press-event",kpe,ent) def ClearIt(wid,ent): ent.set_text('Disabled') def ResetIt(wid,inf): ent = inf[0] set = inf[1] typ = inf[2] vv = set.Value v0 = vv[0] v1 = vv[1] v2 = vv[2] v3 = vv[3] set.ResetToDefault() ent.set_text(set.Value[typ]) set.Value = [v0,v1,v2,v3] def BindingPopup(wid,path,col,Info): global AllowUpdate #why does this get a tuple? that makes no sense. spath = None for foo in path: if (spath): spath = spath+':'+str(foo) else: spath = str(foo) if (Info): MyStore = Info.StoreFiltered else: MyStore = GenStoreFiltered Iter = MyStore.get_iter_from_string(spath) if not Iter: return if (MyStore.iter_has_child(Iter)): if (wid.row_expanded(spath)): wid.collapse_row(spath) else: wid.expand_row(spath,False) return if Info: vals = MyStore.get(Iter,5) set = Info.Plugin.Setting(vals[0]) else: vals = GenStoreFiltered.get(Iter,5,6) set = Ctx.Plugin(vals[0]).Setting(vals[1]) if (set.ReadOnly): return dlg = gtk.Dialog("Edit Shortcuts for %s"%set.ShortDesc,MainWindow,gtk.DIALOG_MODAL,(gtk.STOCK_OK,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) vb = dlg.vbox tb = gtk.Table() tb.props.border_width = 5 tb.props.row_spacing = 5 tb.props.column_spacing = 5 vb.pack_start(tb,False,False) kent = None bent = None if (set.Restrictions[0]): lab = gtk.Label(_("Keyboard Binding:")) lab.props.xalign = 1 tb.attach(lab,0,1,0,1) ent = gtk.Entry() ent.set_text(set.Value[0]) tb.attach(ent,1,2,0,1) grab = gtk.Button(_("Grab Key")) tb.attach(grab,2,3,0,1) grab.connect("clicked",GetKey,ent) clear = gtk.Button("Clear") clear.connect("clicked",ClearIt,ent) tb.attach(clear,3,4,0,1) rest = gtk.Button() rest.connect("clicked",ResetIt,(ent,set,0)) rest.props.image = gtk.image_new_from_stock(gtk.STOCK_CLEAR,gtk.ICON_SIZE_BUTTON) tb.attach(rest,4,5,0,1) kent = ent if (set.Restrictions[1]): lab = gtk.Label(_("Mouse Binding:")) lab.props.xalign = 1 tb.attach(lab,0,1,1,2) ent = gtk.Entry() ent.set_text(set.Value[1]) tb.attach(ent,1,2,1,2) clear = gtk.Button(_("Clear")) clear.connect("clicked",ClearIt,ent) tb.attach(clear,3,4,1,2) rest = gtk.Button() rest.connect("clicked",ResetIt,(ent,set,1)) rest.props.image = gtk.image_new_from_stock(gtk.STOCK_CLEAR,gtk.ICON_SIZE_BUTTON) tb.attach(rest,4,5,1,2) bent = ent lbl_desc = gtk.Label(_(set.LongDesc)) vb.pack_start(gtk.HSeparator()) vb.pack_start(lbl_desc,False,False) vb.show_all() ret = dlg.run() if (ret == gtk.RESPONSE_OK): if kent: TrySetBinding(set,0,kent.get_text()) if bent: # We don't really want a Button1 binding if bent.get_text().lower() != "button1": TrySetBinding(set,1,bent.get_text()) AllowUpdate = False RIter = MyStore.convert_iter_to_child_iter(Iter) if Info: Info.Store.set(RIter,1,set.Value[0],3,set.Value[1]) else: GenStore.set(RIter,1,set.Value[0],3,set.Value[1]) WriteSettings() AllowUpdate = True dlg.destroy() def BindingIsVisibleMethod(model,iter,entry): if (model.iter_children(iter)): niter = model.iter_children(iter) while(niter): if (BindingIsVisibleMethod(model,niter,entry)): return True niter = model.iter_next(niter) return False text = entry.get_text() if len(text) == 0: return True dat = ' '.join( model.get(iter,0,1,3) ) for string in text.lower().split(' '): if dat.lower().find(string) < 0: return False return True def UpdateBindingsFilter(foo): global AllowUpdate if not AllowUpdate: return AllowUpdate = False GenStoreFiltered.refilter() AllowUpdate = True def ClearEntry(but,ent): ent.set_text('') def MakeBindingsList(): vbox = gtk.VBox(False,4) hbox = gtk.HBox(False,4) entry = gtk.Entry() clearbut = gtk.Button(gtk.STOCK_CLEAR) clearbut.set_use_stock(True) hbox.pack_start(gtk.Label(_("Search:")),False,False) hbox.pack_start(entry,True,True) hbox.pack_start(clearbut,False,False) vbox.pack_start(hbox,False,False) genview = gtk.TreeView(GenStoreFiltered) nameren = gtk.CellRendererText() genview.insert_column_with_attributes(0,_("Name"),nameren,markup = 0) keyren = gtk.CellRendererText() genview.insert_column_with_attributes(1,_("Keyboard"),keyren,text = 1,editable = 2,sensitive = 2) butren = gtk.CellRendererText() genview.insert_column_with_attributes(2,_("Mouse"),butren,text = 3,editable = 4,sensitive = 4) genview.props.headers_visible = True genview.props.rules_hint = True cont = gtk.ScrolledWindow() #cont.props.height_request = 250 cont.props.hscrollbar_policy = gtk.POLICY_NEVER cont.add(genview) vwinfr = gtk.Frame() vwinfr.props.shadow_type = gtk.SHADOW_IN vwinfr.add(cont) genview.connect("row-activated",BindingPopup,None) keyren.connect("edited",BindChanged,(0,None)) butren.connect("edited",BindChanged,(1,None)) entry.connect("changed",UpdateBindingsFilter) clearbut.connect("clicked",ClearEntry,entry) GenStoreFiltered.set_visible_func(BindingIsVisibleMethod,entry) vbox.pack_start(vwinfr,True,True) return vbox def EdgeChanged(wid,edg): global AllowUpdate if not AllowUpdate: return Iter = wid.get_active_iter() if (not Iter): return vval = wid.get_model().get(Iter,3) if not vval: return oset = Ctx.EdgeOwner(edg) if (oset): vv = oset.Value ne = vv[3] if (ne.__contains__(berylsettings.edgetolist(edg)[0])): ne.remove(berylsettings.edgetolist(edg)[0]) oset.Value = [vv[0],vv[1],vv[2],ne] vals = wid.get_model().get(Iter,1,2) if (vals[0] == '' and vals[1] == ''): WriteSettings() return set = Ctx.Plugin(vals[0]).Setting(vals[1]) vv = set.Value ne = vv[3] if not (ne.__contains__(berylsettings.edgetolist(edg)[0])): ne = ne+berylsettings.edgetolist(edg) set.Value = [vv[0],vv[1],vv[2],ne] WriteSettings() def MakeEdgeWidgets(): global AllowUpdate AllowUpdate = False global EdgeStore tab = gtk.Table() al = gtk.VBox() al.pack_start(tab,False,False) global EdgeBoxes EdgeBoxes = [] for h in range(0,3): newbox = [] for v in range(0,3): if (h != 1 or v != 1): align = gtk.Frame(EdgeDesc[v][h][0]) box = gtk.ComboBox(EdgeStore) cell = gtk.CellRendererText() cell.props.wrap_width = 140 cell.props.wrap_mode = gtk.WRAP_WORD box.pack_start(cell,True) box.add_attribute(cell,'markup',0) box.add_attribute(cell,'sensitive',3) align.add(box) newbox = newbox+[(box,berylsettings.edgelisttomask([EdgeDesc[v][h][1]]))] tab.attach(align,h,h+1,v,v+1) box.connect("changed",EdgeChanged,berylsettings.edgelisttomask([EdgeDesc[v][h][1]])) else: newbox = newbox+[(None,0)] EdgeBoxes = EdgeBoxes+[newbox] UpdateBindingsList(False) AllowUpdate = True return al def RowEdited(wid,path,tex,set): global AllowUpdate if not AllowUpdate: return n = int(path) n = set.ListStore.iter_nth_child(None,n) set.ListStore.set(n,0,tex) SetSettingFromWidgets(set) return True def ClearSet(wid,set): global AllowUpdate if (set.Setting.Type == 'Binding'): vv = set.Setting.Value v0 = vv[0] v1 = vv[1] v3 = vv[3] set.Setting.ResetToDefault() set.Setting.Value = [v0,v1,set.Setting.Value[2],v3] else: set.Setting.ResetToDefault() WriteSettings() AllowUpdate = False SetWidgetsForSetting(set.Setting) AllowUpdate = True def ClearPopupEntry(wid,realwid): realwid.set_text("") Row = 0 def GetXprop(regexp): xprop = os.popen("xprop").readlines() rex = re.compile(regexp) val = "" for line in xprop: if rex.search(line): m = rex.match(line) val = m.group(1).lower().capitalize() return val def PutXprop(set,cbox,centry): if cbox.get_active_text() == "Window Type": val = GetXprop("^_NET_WM_WINDOW_TYPE\(ATOM\) = _NET_WM_WINDOW_TYPE_(\w+)") elif cbox.get_active_text() == "Window Class": val = GetXprop("^WM_CLASS\(STRING\) = \"([^\"]+)\"") elif cbox.get_active_text() == "Window Title": val = GetXprop("^WM_NAME\(STRING\) = \"([^\"]+)\"") elif cbox.get_active_text() == "Owning Program": val = GetXprop("^WM_COMMAND\(STRING\) = \{ \"([^\"]+)\"") elif cbox.get_active_text() == "Window Role": val = GetXprop("^WM_WINDOW_ROLE\(STRING\) = \"([^\"]+)\"") elif cbox.get_active_text() == "Class Name": val = GetXprop("^WM_CLASS\(STRING\) = \"[^\"]+\", \"([^\"]+)\"") centry.set_text(val) def StatePopup(button,set): dlg = gtk.Dialog(_("Add criteria for window attribute"),MainWindow,gtk.DIALOG_MODAL,(gtk.STOCK_OK,gtk.RESPONSE_OK,gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) vbox = dlg.vbox sldr = gtk.HBox(False,8) hbox = gtk.HBox(False,8) vrow = gtk.HBox(False,8) lrow = gtk.HBox(False,8) vbox.pack_start(sldr,True,True) vbox.pack_start(hbox,False,False) vbox.pack_start(vrow,True,True) vbox.pack_start(lrow,True,True) ld = gtk.Label(set.Setting.LongDesc) ld.set_width_chars(50) ld.set_line_wrap(True) sldr.pack_start(ld,True,True) pcombo = gtk.combo_box_new_text() for property in ["Window Type","Window Class","Window Title",\ "Owning Program","Class Name","Class Role"]: pcombo.append_text(property) pval = gtk.Entry() pcombo.connect("changed",ClearPopupEntry,pval) pval.width_chars = 15 grab = gtk.Button("Grab") grab.connect("clicked",PutXprop,pcombo,pval) if set.Setting.Name in ("opacity","brightness","saturation","opacityabs","brightnessabs","saturationabs"): Adj = gtk.Adjustment(0,0,100,1) bat = gtk.SpinButton(Adj,1,0) valwid = gtk.HScale(Adj) valwid.props.digits = 0 vrow.pack_end(bat,True,True) elif set.Setting.Name == "viewport": hsize = Ctx.Plugin("_").Setting("size").Value Adj = gtk.Adjustment(0,0,hsize,1) valwid = gtk.combo_box_new_text() for i in range(hsize): valwid.append_text(str(i)) elif set.Setting.Name in ("border","noargb"): valwid = gtk.CheckButton(set.Setting.ShortDesc) valwid.set_active(True) elif set.Setting.Name == "position": valwid = gtk.combo_box_new_text() valwid.append_text(_("Top Left")) valwid.append_text(_("Top Center")) valwid.append_text(_("Top Right")) valwid.append_text(_("Center Left")) valwid.append_text(_("Center")) valwid.append_text(_("Center Right")) valwid.append_text(_("Bottom Left")) valwid.append_text(_("Bottom Center")) valwid.append_text(_("Bottom Right")) lbl = gtk.Label(_("\nSelect the window attribute. Click the Grab button to select a window, then choose a value for the setting.")) lbl.set_width_chars(50) lbl.set_line_wrap(True) lrow.pack_start(lbl,True,True) lrow.show_all() sldr.show_all() hbox.pack_start(pcombo,False,False) hbox.pack_start(pval,False,False) hbox.pack_start(grab,False,False) vrow.pack_start(valwid,True,True) hbox.show_all() vrow.show_all() ret = dlg.run() if (ret == gtk.RESPONSE_OK): propname = pcombo.get_active_text() propval = pval.get_text() if set.Setting.Name == "viewport": val = valwid.get_active_text() elif set.Setting.Name in ("border","noargb"): if valwid.get_active(): val = "1" else: val = "0" elif set.Setting.Name == "position": val = str(valwid.get_active()+1) else: val = str(int(bat.get_value())) if propname != None and propval != None and val != None: AddStateProp(pcombo.get_active_text(),pval.get_text(),val,set) dlg.destroy() def AddStateProp(cval,tval,val,set): if cval == "Window Type": let = "w" elif cval == "Window Class": let = "c" elif cval == "Window Title": let = "t" elif cval == "Owning Program": let = "p" elif cval == "Class Name": let = "n" elif cval == "Class Role": let = "r" inspos = set.TreeView.get_selection().get_selected()[1] if (inspos): Iter = set.ListStore.insert_after(inspos) else: Iter = set.ListStore.append() set.ListStore.set(Iter,0,let + ':' + tval + ':' + val) SetSettingFromWidgets(set) def MakeAndConnect(wid,setting): global AllSettings global Row resbut = gtk.Button() resbut.props.image = gtk.image_new_from_stock(gtk.STOCK_CLEAR,gtk.ICON_SIZE_BUTTON) SetInfo = FooClass() SetInfo.Setting = setting SetWid = [] lab = gtk.Label(setting.ShortDesc) SetInfo.Label = lab SetInfo.ResetButton = resbut if (setting.Type == 'Bool'): foo = gtk.HBox(False,8) foo.pack_start(resbut,False,False) foo.pack_start(lab,False,False) ebox = gtk.EventBox() ebox.add(foo) wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK) bar = gtk.CheckButton() bar.props.xalign = 0 tooltips.set_tip(ebox,setting.LongDesc) tooltips.set_tip(bar,setting.LongDesc) wid.attach(bar,1,2,Row,Row+1) SetInfo.Checkbox = bar bar.connect("toggled",SimpleChangedCB,SetInfo) elif (setting.Type == 'Binding' and setting.Restrictions[2]): foo = gtk.HBox(False,8) foo.pack_start(resbut,False,False) lab.set_text("%s on system bell"%setting.ShortDesc) foo.pack_start(lab,False,False) ebox = gtk.EventBox() ebox.add(foo) wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK) bar = gtk.CheckButton() bar.props.xalign = 0 tooltips.set_tip(bar,setting.LongDesc) tooltips.set_tip(ebox,setting.LongDesc) wid.attach(bar,1,2,Row,Row+1) SetInfo.Checkbox = bar bar.connect("toggled",SimpleChangedCB,SetInfo) elif (setting.Type == 'List of String'): if (len(setting.Restrictions)): foo = gtk.Frame(setting.ShortDesc) bar = gtk.HBox(False,8) bar.props.border_width = 4 ebox = gtk.EventBox() ebox.add(bar) tooltips.set_tip(ebox,setting.LongDesc) foo.add(ebox) baz = gtk.VBox(False,0) bar.pack_start(baz,False,False) baz.pack_start(resbut,False,False) checkies = [] row = 0 col = 0 checkCont = gtk.Table() for m in setting.Restrictions: ss = gtk.CheckButton(m) CheckInfo = FooClass() CheckInfo.String = m CheckInfo.Checkbox = ss checkies = checkies+[CheckInfo] checkCont.attach(ss,col,col+1,row,row+1) col = col+1 if (col>3): col = 0 row = row+1 bar.pack_start(checkCont,True,True) SetInfo.CheckBoxes = checkies for bar in checkies: bar.Checkbox.connect("toggled",SimpleChangedCB,SetInfo) else: foo = gtk.Frame(setting.ShortDesc) bar = gtk.HBox(False,8) ebox = gtk.EventBox() ebox.add(bar) bar.props.border_width = 4 foo.add(ebox) tooltips.set_tip(ebox,setting.LongDesc) bil = gtk.ListStore(gobject.TYPE_STRING) foob = gtk.ScrolledWindow() foob.props.hscrollbar_policy = gtk.POLICY_NEVER foob.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC foob.props.shadow_type = gtk.SHADOW_IN baz = gtk.TreeView(bil) foob.add(baz) ren = gtk.CellRendererText() ren.props.editable = True baz.insert_column_with_attributes(0,"Value",ren,text = 0) baz.props.headers_visible = False baz.props.height_request = 100 fib = gtk.VBox() fib.pack_start(resbut,False,False) bar.pack_start(fib,False,False) bar.pack_start(foob,True,True) tab = gtk.Table(homogeneous = True) delete = gtk.Button() delete.props.image = gtk.image_new_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_BUTTON) add = gtk.Button() add.props.image = gtk.image_new_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_BUTTON) if setting.Plugin.Name == "state": add.connect("clicked",StatePopup,SetInfo) else: up = gtk.Button() up.props.image = gtk.image_new_from_stock(gtk.STOCK_GO_UP,gtk.ICON_SIZE_BUTTON) dn = gtk.Button() dn.props.image = gtk.image_new_from_stock(gtk.STOCK_GO_DOWN,gtk.ICON_SIZE_BUTTON) up.connect("clicked",MoveRow,(0,SetInfo)) dn.connect("clicked",MoveRow,(1,SetInfo)) add.connect("clicked",AddRow,SetInfo) tab.attach(up,0,1,0,1) tab.attach(dn,0,1,2,3) SetInfo.ListStore = bil SetInfo.TreeView = baz if (setting.HasHint("file")): brw = gtk.Button(_("Browse")) brw.props.image = gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON) brw.connect("clicked",BrowseRow,SetInfo) tooltips.set_tip(brw,setting.LongDesc) tab.attach(brw,0,2,1,2) delete.connect("clicked",DelRow,SetInfo) tab.attach(add,1,2,0,1) tab.attach(delete,1,2,2,3) bar.pack_start(tab,False,False) ren.connect("edited",RowEdited,SetInfo) wid.attach(foo,0,2,Row,Row+1) elif (setting.Type == 'String'): foo = gtk.HBox(False,8) foo.pack_start(resbut,False,False) foo.pack_start(lab,False,False) ebox = gtk.EventBox() ebox.add(foo) wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK) tooltips.set_tip(ebox,setting.LongDesc) if (len(setting.Restrictions)): bar = gtk.combo_box_new_text() for m in setting.Restrictions: bar.append_text(m) SetInfo.ComboBox = bar else: bar = gtk.Entry() bar.props.width_chars = 30 SetInfo.Entry = bar foo = gtk.HBox(False,8) foo.pack_start(bar,True,True) ebox = gtk.EventBox() ebox.add(foo) tooltips.set_tip(ebox,setting.LongDesc) if (setting.HasHint("file")): bar.props.width_chars = 25 brw = gtk.Button("Browse") brw.props.image = gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON) brw.connect("clicked",BrowseEntry,SetInfo) tooltips.set_tip(brw,setting.LongDesc) foo.pack_start(brw,False,False) wid.attach(ebox,1,2,Row,Row+1) bar.connect("changed",SimpleChangedCB,SetInfo) elif (setting.Type == 'Int' or setting.Type == 'Float'): foo = gtk.HBox(False,8) foo.pack_start(resbut,False,False) foo.pack_start(lab,False,False) ebox = gtk.EventBox() ebox.add(foo) tooltips.set_tip(ebox,setting.LongDesc) wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK) foo = gtk.HBox(False,8) if (len(setting.Restrictions)>2): Adj = gtk.Adjustment(setting.Value,setting.Restrictions[0],setting.Restrictions[1],setting.Restrictions[2]) bat = gtk.SpinButton(Adj,setting.Restrictions[2],4) ban = gtk.HScale(Adj) tooltips.set_tip(ban,setting.LongDesc) ban.props.digits = 4 else: Adj = gtk.Adjustment(setting.Value,setting.Restrictions[0],setting.Restrictions[1],1) bat = gtk.SpinButton(Adj,1,0) ban = gtk.HScale(Adj) tooltips.set_tip(ban,setting.LongDesc) ban.props.digits = 0 ban.props.update_policy = gtk.UPDATE_DISCONTINUOUS bat.props.update_policy = gtk.UPDATE_IF_VALID ban.props.draw_value = False bat.props.width_chars = 6 bat.set_editable(True) tooltips.set_tip(bat,setting.LongDesc) hb = gtk.HBox(False,8) wid.attach(hb,1,2,Row,Row+1) hb.pack_start(ban,True,True) hb.pack_start(bat,False,False) SetInfo.SpinButton = bat SetInfo.HScale = ban ban.connect("value-changed",SimpleChangedCB,SetInfo) elif (setting.Type == 'Color'): foo = gtk.HBox(False,8) foo.pack_start(resbut,False,False) foo.pack_start(lab,False,False) ebox = gtk.EventBox() ebox.add(foo) tooltips.set_tip(ebox,setting.LongDesc) wid.attach(ebox,0,1,Row,Row+1,gtk.SHRINK) foo = gtk.HBox(False,8) bar = gtk.ColorButton() tooltips.set_tip(bar,setting.LongDesc) foo.pack_start(bar,False,False) bar.props.use_alpha = True wid.attach(foo,1,2,Row,Row+1) SetInfo.ColorButton = bar bar.connect("color-set",SimpleChangedCB,SetInfo) else: return False lab.props.wrap = True lab.props.width_request = 250 lab.props.xalign = 0 Row = Row+1 resbut.connect("clicked",ClearSet,SetInfo) AllSettings = AllSettings+[SetInfo] return True def DoFilter(foo,Store): Store.refilter() def MakeBindingsListForPlugin(Plugin): BindVBox = gtk.VBox(False,4) EntHBox = gtk.HBox(False,4) entry = gtk.Entry() clearbut = gtk.Button(gtk.STOCK_CLEAR) clearbut.set_use_stock(True) EntHBox.pack_start(gtk.Label(_("Search:")),False,False) EntHBox.pack_start(entry,True,True) EntHBox.pack_start(clearbut,False,False) BindVBox.pack_start(EntHBox,False,False) Store = gtk.TreeStore( gobject.TYPE_STRING, #Entry Name gobject.TYPE_STRING, #Key binding gobject.TYPE_BOOLEAN, #key enabled gobject.TYPE_STRING, #Button binding gobject.TYPE_BOOLEAN, #button enabled gobject.TYPE_STRING, #setting name ) StoreFiltered = Store.filter_new() View = gtk.TreeView(StoreFiltered) Scroll = gtk.ScrolledWindow() Scroll.props.hscrollbar_policy = gtk.POLICY_NEVER Scroll.add(View) vwinfr = gtk.Frame() vwinfr.props.shadow_type = gtk.SHADOW_IN vwinfr.add(Scroll) BindVBox.pack_start(vwinfr,True,True) nameren = gtk.CellRendererText() View.insert_column_with_attributes(0,_("Name"),nameren,markup = 0) keyren = gtk.CellRendererText() View.insert_column_with_attributes(1,_("Keyboard"),keyren,text = 1,editable = 2,sensitive = 2) butren = gtk.CellRendererText() View.insert_column_with_attributes(2,_("Mouse"),butren,text = 3,editable = 4,sensitive = 4) View.props.headers_visible = True View.props.rules_hint = True hasany = False StoreFiltered.set_visible_func(BindingIsVisibleMethod,entry) for G in Plugin.Groups: GSettings = [S for S in Plugin.Settings if S.Group == G.Name and S.Type == 'Binding' and (S.Restrictions[0] or S.Restrictions[1])] if len(G.SubGroups) and not (G.Name == '') and len(GSettings): GIter = Store.append(None) Store.set(GIter,0,G.Name) else: GIter = None for S in GSettings: hasany = True Iter = Store.append(GIter) if (S.Restrictions[0]): mv0 = S.Value[0] else: mv0 = "N/A" if (S.Restrictions[1]): mv1 = S.Value[1] else: mv1 = "N/A" if (S.Integrated): Store.set(Iter,0,"<span foreground=\"blue\">%s</span>"%(S.ShortDesc),1,mv0,2,S.Restrictions[0] and not S.ReadOnly, 3,mv1,4,S.Restrictions[1] and not S.ReadOnly,5,S.Name) else: Store.set(Iter,0,S.ShortDesc,1,mv0,2,S.Restrictions[0] and not S.ReadOnly, 3,mv1,4,S.Restrictions[1] and not S.ReadOnly,5,S.Name) Info = FooClass() Info.Plugin = Plugin Info.Store = Store Info.StoreFiltered = StoreFiltered clearbut.connect("clicked",ClearEntry,entry) entry.connect("changed",DoFilter,StoreFiltered) View.connect("row-activated",BindingPopup,Info) keyren.connect("edited",BindChanged,(0,Info)) butren.connect("edited",BindChanged,(1,Info)) if hasany: return BindVBox return None def ProfileSelChanged(sel,ent): Inf = sel.get_selected() if Inf[1] and Inf[0].get(Inf[1],0)[0]: ent.set_text(Inf[0].get(Inf[1],0)[0]) else: ent.set_text('') def MakeProfileWidgets(): global CurProfLab global CurProfStore global CurProfView all = gtk.VBox(False,4) CurProfLab = gtk.Label() CurProfLab.props.xalign = 0 all.pack_start(CurProfLab,False,False) row = gtk.HBox(False,4) all.pack_start(row,False,False) ent = gtk.Entry() row.pack_start(ent,True,True) addchbut = gtk.Button(_('Add/Save')) row.pack_start(addchbut,False,False) loadbut = gtk.Button(_('Load/Activate')) row.pack_start(loadbut,False,False) delbut = gtk.Button(_('Delete')) row.pack_start(delbut,False,False) CurProfStore = gtk.ListStore(gobject.TYPE_STRING) CurProfView = gtk.TreeView(CurProfStore) vwin = gtk.ScrolledWindow() vwinfr = gtk.Frame() vwinfr.props.shadow_type = gtk.SHADOW_IN vwin.props.hscrollbar_policy = gtk.POLICY_NEVER vwin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC vwin.add(CurProfView) texren = gtk.CellRendererText() CurProfView.insert_column_with_attributes(0,"Profile",texren,text = 0) vwinfr.add(vwin) all.pack_start(vwinfr,True,True) viewsel = CurProfView.get_selection() viewsel.connect("changed",ProfileSelChanged,ent) CurProfView.connect("row-activated",ProfileRowActive,ent) UpdateProfileStore() addchbut.connect("clicked",SaveProfile,ent) loadbut.connect("clicked",LoadProfile,ent) delbut.connect("clicked",DeleteProfile,ent) return all def ProfileRowActive(wid,path,col,ent): LoadProfile(None,ent) def SaveProfile(wid,ent): val = ent.get_text() if (val == ''): return # silently ignore this silliness if (val == _('<Default>')): val = None Ctx.Profile = val WriteSettings() UpdateProfileStore() def LoadProfile(wid,ent): val = ent.get_text() if (val == ''): return # silently ignore this silliness if (val == _('<Default>')): val = None Ctx.Profile = val Ctx.Read() SetWidgetsFromValues() WriteSettings() UpdateProfileStore() def DeleteProfile(wid,ent): val = ent.get_text() if (val == ''): return # silently ignore this silliness if (val == _('<Default>')): val = None Ctx.DeleteProfile(val) if (Ctx.Profile == val): Ctx.Profile = None Ctx.Read() SetWidgetsFromValues() WriteSettings() UpdateProfileStore() def UpdateProfileStore(): global CurProfStore global CurProfView CurProfStore.clear() viewsel = CurProfView.get_selection() Iter = CurProfStore.append() CurProfStore.set(Iter,0,_('<Default>')) if not Ctx.Profile: viewsel.select_iter(Iter) for p in Ctx.Profiles: Iter = CurProfStore.append() CurProfStore.set(Iter,0,p) if p == Ctx.Profile: viewsel.select_iter(Iter) def MakeBackendWidgets(): tab = gtk.Table() BackendStore = gtk.ListStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_BOOLEAN) for backend in berylsettings.Backends(): Iter = BackendStore.append() BackendStore.set(Iter,0,backend.Name,1,backend.ShortDesc,2,backend.IntegrationSupport) BackendBox = gtk.ComboBox(BackendStore) BackendRend = gtk.CellRendererText() BackendBox.pack_start(BackendRend) BackendBox.add_attribute(BackendRend,"text",1) lab = gtk.Label(_('DE and Settings Backend')) lab.props.wrap = True lab.props.width_request = 250 lab.props.xalign = 0 tab.attach(lab,0,1,0,1) tab.attach(BackendBox,1,2,0,1) actv = Ctx.Backend Iter = BackendStore.get_iter_first() lab = gtk.Label(_("Enable DE Integration for Backend")) lab.props.wrap = True lab.props.width_request = 250 lab.props.xalign = 0 tab.attach(lab,0,1,1,2) IntegButton = gtk.CheckButton() IntegButton.set_active(Ctx.Integrated) tab.attach(IntegButton,1,2,1,2) while(True): m = BackendStore.get(Iter,0,2) if (m[0]==actv): BackendBox.set_active_iter(Iter) IntegButton.set_sensitive(m[1]) break Iter = BackendStore.iter_next(Iter) if not Iter: break BackendBox.connect("changed",SetActiveBackend,(BackendStore,IntegButton)) IntegButton.connect("toggled",SetIntegrated) tabBox = gtk.VBox(False,0) tabBox.pack_start(tab,False,False) return tabBox def MakeSubGroupArea(SubGroup,GroupVBox): global Row if (SubGroup.Name == '__keymouse'): UpdateBindingsList(False) GroupVBox.pack_start(MakeBindingsList(),True,True) return True if (SubGroup.Name == '__shortcuts_for_plugin'): wid = MakeBindingsListForPlugin(SubGroup.Plugin) if (wid): GroupVBox.pack_start(wid,True,True) return True return False if (SubGroup.Name == '__edges'): GroupVBox.pack_start(MakeEdgeWidgets(),True,True) return True if (SubGroup.Name == '__profiles'): GroupVBox.pack_start(MakeProfileWidgets(),True,True) return True if (SubGroup.Name == '__backends'): GroupVBox.pack_start(MakeBackendWidgets(),True,True) return True GroupContainer = GroupVBox Frame = None if not SubGroup.Name == '': Frame = gtk.Frame() Expander = gtk.Expander(SubGroup.Name) Frame.add(Expander) GroupContainer = gtk.VBox() Expander.add(GroupContainer) hasany = False Table = gtk.Table() Table.props.row_spacing = 4 Row = 0 GroupContainer.pack_start(Table,False,False) for Setting in SubGroup.Settings: if (not Setting.Advanced): if (MakeAndConnect(Table,Setting)): hasany = True AdvFrame = gtk.Frame() AdvExpander = gtk.Expander(_("Advanced")) AdvFrame.add(AdvExpander) AdvVBox = gtk.VBox() AdvExpander.add(AdvVBox) AdvTable = gtk.Table() AdvTable.props.row_spacing = 4 Row = 0 AdvVBox.pack_start(AdvTable,False,False) hasAdvanced = False for Setting in SubGroup.Settings: if (Setting.Advanced): if (MakeAndConnect(AdvTable,Setting)): hasAdvanced = True hasany = True if hasAdvanced: GroupContainer.pack_start(AdvFrame,False,False) #otherwise it just falls out of scope if (hasany and Frame): GroupVBox.pack_start(Frame,False,False) #same as above return hasany def MakeGroupArea(Group,NoteBook): VBox = gtk.VBox(False,4) Viewport = gtk.Viewport() Viewport.props.shadow_type = gtk.SHADOW_NONE ScrollWin = gtk.ScrolledWindow() ScrollWin.props.hscrollbar_policy = gtk.POLICY_NEVER ScrollWin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC Viewport.add(VBox) ScrollWin.add(Viewport) hasany = False NoteBook.append_page(ScrollWin,gtk.Label(Group.Name)) VBox.props.border_width = 4 for SubGroup in Group.SubGroups: if (MakeSubGroupArea(SubGroup,VBox)): hasany = True if not hasany: NoteBook.remove_page(-1) def MakePluginArea(Plugin): global hideshowall Image = gtk.Image() if (Plugin.Name == '__bindings'): try: BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/shortcuts.svg",IconSize,IconSize) except: BasePixbuf = gdk.pixbuf_new_from_file_at_size(PREFIX+"/share/beryl/icon.png",IconSize,IconSize) elif (Plugin.Name == '__settings'): try: BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/profile-backends.svg",IconSize,IconSize) except: BasePixbuf = gdk.pixbuf_new_from_file_at_size(PREFIX+"/share/beryl/icon.png",IconSize,IconSize) else: try: BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/beryl-settings-section-%s.svg"%(Plugin.Name),IconSize,IconSize) except: try: BasePixbuf = gdk.pixbuf_new_from_file_at_size(IMAGEDIR+"/beryl-settings-section-%s.png"%(Plugin.Name),IconSize,IconSize) except: BasePixbuf = gdk.pixbuf_new_from_file_at_size(PREFIX+"/share/beryl/icon.png",IconSize,IconSize) HighPixbuf = BasePixbuf.copy() HighPixbuf.saturate_and_pixelate(HighPixbuf,6.0,True) Image.set_from_pixbuf(BasePixbuf) ListEventBox = gtk.EventBox() ListHBox = gtk.HBox(False,8) ListEventBox.add(ListHBox) if (not (Category.Name == '__general')): EnableButton = gtk.CheckButton() ListHBox.pack_start(EnableButton,False,False) else: EnableButton = None ListHBox.pack_start(Image,False,False) Label = gtk.Label() Label.set_markup("<small>%s</small>"%(Plugin.ShortDesc)) Label.set_size_request(120,-1) Label.set_line_wrap(True) ListHBox.pack_start(Label,False,False) Container = gtk.VBox(False,4) HeaderBox = gtk.HBox(False,8) HeaderImage = gtk.Image() HeaderImage.set_from_pixbuf(BasePixbuf) HeaderBox.pack_start(HeaderImage,False,False,0) HeaderLabel = gtk.Label() HeaderLabel.set_markup("<b><big>%s</big></b>\n<i>%s</i>"%(Plugin.ShortDesc,Plugin.LongDesc)) HeaderLabel.props.wrap = True if (HeaderLabel.size_request()[0]>400): HeaderLabel.props.width_request = 400 HeaderLabel.props.xalign = 0 HeaderBox.pack_start(HeaderLabel,True,True,0) Container.pack_start(HeaderBox,False,False) if (Plugin.Name == '__bindings'): hideshowall = gtk.CheckButton(_("Show Disabled Plugins")) hideshowall.props.active = False hideshowall.connect("clicked",HideShowClick) Container.pack_start(hideshowall,False,False) NoteBook = gtk.Notebook() NoteBook.props.scrollable = True Container.pack_start(NoteBook,True,True) for Group in Plugin.Groups: MakeGroupArea(Group,NoteBook) if (not Category.Name == "__general" or Plugin.Name == '_'): BindGroup = FooClass() BindSubGroup = FooClass() BindGroup.Name = _('Shortcuts') BindGroup.SubGroups = [BindSubGroup] BindSubGroup.Name = '__shortcuts_for_plugin' BindSubGroup.Plugin = Plugin MakeGroupArea(BindGroup,NoteBook) Info = FooClass() Info.BasePixbuf = BasePixbuf Info.HighPixbuf = HighPixbuf Info.Image = Image Info.Label = Label Info.Plugin = Plugin Info.Widget = Container Info.Button = EnableButton Info.ListEventBox = ListEventBox if EnableButton: Info.HasEnableButton = True Info.EnableButton = EnableButton else: Info.HasEnableButton = False return Info def MakeCategoryArea(Category): global AllCats global Row Image = gtk.Image() CatBasePixbuf = gdk.pixbuf_new_from_file_at_size("%s/%s"%(BaseDir,CatImages[Category.Name]),IconSize,IconSize) HighPixbuf = CatBasePixbuf.copy() HighPixbuf.saturate_and_pixelate(HighPixbuf,6.0,True) Image.set_from_pixbuf(CatBasePixbuf) Label = gtk.Label() Label.set_markup("<small>%s</small>"%(Category.ShortDesc)) Label.props.wrap = True Label.props.width_request = MaxWidth Label.props.justify = gtk.JUSTIFY_CENTER ListEventBox = gtk.EventBox() VBox = gtk.VBox() VBox.pack_start(Image,False,False) VBox.pack_end(Label,True,True) ListEventBox.add(VBox) CategoryBox.pack_start(ListEventBox) Container = gtk.VBox() HeaderBox = gtk.HBox() Container.pack_start(HeaderBox,False,False) HeaderImage = gtk.Image() HeaderImage.set_from_pixbuf(CatBasePixbuf) HeaderBox.pack_start(HeaderImage,False,False,8) HeaderLabel = gtk.Label() HeaderLabel.set_markup("<b><big>%s</big></b>\n<i>%s</i>"%(Category.ShortDesc,Category.LongDesc)) HeaderLabel.props.xalign = 0 HeaderBox.pack_start(HeaderLabel,True,True,8) FormatBox = gtk.HBox(False,0) Container.pack_start(FormatBox,True,True,8) ContentFrame = gtk.Frame() FormatBox.pack_start(ContentFrame,True,True,8) ContentHBox = gtk.HBox(False,8) PluginListFrame = gtk.Frame() PluginListScrollWin = gtk.ScrolledWindow() PluginListViewport = gtk.Viewport() PluginListViewport.props.shadow_type = gtk.SHADOW_NONE PluginListScrollWin.props.hscrollbar_policy = gtk.POLICY_NEVER PluginListScrollWin.props.vscrollbar_policy = gtk.POLICY_AUTOMATIC PluginList = gtk.VBox() PluginListViewport.add(PluginList) PluginListScrollWin.add(PluginListViewport) PluginList.props.border_width = 4 PluginListFrame.add(PluginListScrollWin) ContentHBox.pack_start(PluginListFrame,False,False,0) ContentHBox.props.border_width = 8 ContentFrame.add(ContentHBox) PluginContainer = gtk.Alignment() PluginContainer.props.xalign = 0 PluginContainer.props.yalign = 0 PluginContainer.props.xscale = 1 PluginContainer.props.yscale = 1 ContentHBox.pack_start(PluginContainer,True,True,0) Plugins = [] SortedPluginList = Category.Plugins #alpha-sort plugin list if not Category.Name == '__general': for j in range(0,len(SortedPluginList)-1): for k in range(j+1,len(SortedPluginList)): if (SortedPluginList[j].ShortDesc>SortedPluginList[k].ShortDesc): TempStorage = SortedPluginList[j] SortedPluginList[j] = SortedPluginList[k] SortedPluginList[k] = TempStorage for Plugin in SortedPluginList: if (Plugin.Name == '_' and not (Category.Name == '__general')): continue PlugInfo = MakePluginArea(Plugin) PlugInfo.CatIndex = len(AllCats) PlugInfo.Index = len(Plugins) Plugins = Plugins+[PlugInfo] PlugInfo.ListEventBox.connect("button-press-event",PlugClicked,PlugInfo) if (PlugInfo.HasEnableButton): PlugInfo.EnableButton.connect("toggled",PluginButtonClicked,PlugInfo) PluginList.pack_start(PlugInfo.ListEventBox,False,False) CatInfo = FooClass() CatInfo.BasePixbuf = CatBasePixbuf CatInfo.HighPixbuf = HighPixbuf CatInfo.Image = Image CatInfo.Label = Label CatInfo.Widget = Container CatInfo.Category = Category CatInfo.Index = len(AllCats) CatInfo.Plugins = Plugins CatInfo.Container = PluginContainer AllCats = AllCats+[CatInfo] ListEventBox.connect("button-press-event",CatClicked,CatInfo) def ImportSettings(wid): ImportWindow = gtk.FileChooserDialog(_("Import settings file..."),MainWindow, gtk.FILE_CHOOSER_ACTION_OPEN,(gtk.STOCK_OPEN,gtk.RESPONSE_OK, gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) fil = gtk.FileFilter() fil.set_name(_("All Files")) fil.add_pattern("*") ImportWindow.add_filter(fil) ImportWindow.set_filter(fil) ret = ImportWindow.run() if (ret == gtk.RESPONSE_OK): val = ImportWindow.get_filename() if (val): Ctx.Import(val,True) ImportWindow.destroy() del ImportWindow def ExportSettings(wid): ExportWindow = gtk.FileChooserDialog(_("Export settings file..."),MainWindow, gtk.FILE_CHOOSER_ACTION_SAVE,(gtk.STOCK_SAVE,gtk.RESPONSE_OK, gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL)) fil = gtk.FileFilter() fil.set_name(_("Settings Files")) fil.add_pattern("*.settings") ExportWindow.set_filter(fil) ret = ExportWindow.run() if (ret == gtk.RESPONSE_OK): val = ExportWindow.get_filename() if (val): Ctx.Export(val) ExportWindow.destroy() del ExportWindow def SetActiveBackend(wid,info): Iter = wid.get_active_iter() dat = info[0].get(Iter,0,2) Ctx.Backend = dat[0] info[1].set_sensitive(dat[1]) UpdateProfileStore() SetWidgetsFromValues() def SetIntegrated(wid): Ctx.Integrated = wid.props.active SetWidgetsFromValues() MainWindow = gtk.Window() MainChild = gtk.VBox() MainWindow.add(MainChild) version = VERSION MainWindow.set_title(_("Beryl Settings Manager")) try: MainWindow.set_icon (gdk.pixbuf_new_from_file(DATADIR+"/icons/hicolor/scalable/apps/beryl-settings.svg")) except: pass #MainWindow.set_resizable(False) MainWindow.set_size_request(-1,580) #MainWindow.get_size_request()[0],580) CategoryStrip = gtk.Alignment() CategoryStrip.props.xalign = 0.5 CategoryStrip.props.yalign = 0.5 CategoryStrip.props.xscale = 0 CategoryStrip.props.yscale = 0 CategoryBox = gtk.HBox(True) CategoryStrip.add(CategoryBox) PlugArea = gtk.Alignment() PlugArea.props.xalign = 0 PlugArea.props.yalign = 0 PlugArea.props.xscale = 1 PlugArea.props.yscale = 1 MainChild.pack_start(CategoryStrip,False,False) MainChild.pack_start(gtk.HSeparator(),False,False) MainChild.pack_start(gtk.HSeparator(),False,False) MainChild.pack_start(PlugArea,True,True) ButtonRow = gtk.HBox() ButtonRow.props.border_width = 0 MainChild.pack_start(ButtonRow,False,False) MainChild.pack_start(gtk.Alignment(),False,False,4) ImportButton = gtk.Button(_("Import")) ImportButton.props.image = gtk.image_new_from_stock(gtk.STOCK_OPEN,gtk.ICON_SIZE_BUTTON) ButtonRow.pack_start(ImportButton,False,False,8) ImportButton.connect("clicked",ImportSettings) ExportButton = gtk.Button(_("Export")) ExportButton.props.image = gtk.image_new_from_stock(gtk.STOCK_SAVE,gtk.ICON_SIZE_BUTTON) ButtonRow.pack_start(ExportButton,False,False,0) ExportButton.connect("clicked",ExportSettings) QButton = gtk.Button(gtk.STOCK_QUIT) QButton.set_use_stock(True) ButtonRow.pack_end(QButton,False,False,8) QButton.connect("clicked",QuitAll) IconSize = 48 MaxWidth = 112 Bind = FooClass() Edge = FooClass() NonCat = FooClass() KeyMouse = FooClass() EdSub = FooClass() EdSub.Name = "__edges" Edge.Name = _("Screen Edges") Edge.SubGroups = [EdSub] KeyMouse.Name = _("Keyboard and Mouse") BindSub = FooClass() BindSub.Name = "__keymouse" KeyMouse.SubGroups = [BindSub] Bind.Name = "__bindings" Bind.ShortDesc = _("Shortcuts") Bind.LongDesc = _('Key, Mouse and Edge Shortcuts (Bindings)') Bind.Groups = [KeyMouse,Edge] SettProf = FooClass() SettProf.Name = _('Profiles') SettPSub = FooClass() SettPSub.Name = '__profiles' SettProf.SubGroups = [SettPSub] SettBack = FooClass() SettBack.Name = _('Backends and Integration') SettBSub = FooClass() SettBSub.Name = '__backends' SettBack.SubGroups = [SettBSub] Sett = FooClass() Sett.Groups = [SettProf,SettBack] Sett.Name = "__settings" Sett.ShortDesc = _('Settings, Profiles and Desktop Integration') Sett.LongDesc = _('Options for Settings storage, Settings Profiles, and Desktop Integration') NonCat.Name = '__general' NonCat.ShortDesc = _('General Options') NonCat.LongDesc = _('Beryl Core Options - Options which are part of the core of beryl, and are not part of the plugins.') NonCat.Plugins = [Ctx.Plugin("_"),Bind,Sett] for Category in [NonCat]+Ctx.Categories: if (Category.Name == "settings"): continue if (len(Category.Plugins) == 1): if (Category.Plugins[0].Name == "_"): continue if (len(Category.Plugins)>0): MakeCategoryArea(Category) SetWidgetsFromValues() CatClicked(None,None,AllCats[0]) for Cat in AllCats: PlugClicked(None,None,Cat.Plugins[0]) MainWindow.connect("destroy",QuitAll) MainWindow.show_all() gtk.main()